<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>06_列表渲染</title>
</head>
<body>

<!--
1. 列表显示
  数组: v-for / index
  对象: v-for / key
  建议尽可能在使用 v-for 时提供 key attribute，因为它是 Vue 识别节点的一个通用机制；除非遍历输出的 DOM 内容非常简单，或者是刻意依赖默认行为以获取性能上的提升。
2. 列表的更新显示
  删除item
  替换item
-->

<div id="demo">
  <h2>测试: v-for 遍历数组</h2>
  <ul>
    <li v-for="(p, index) in persons" :key="index">
      {{index}}--{{p.name}}--{{p.age}}
      --<button @click="deleteP(index)">删除</button>
      --<button @click="updateP(index, {name:'Cat', age: 16})">更新</button>
    </li>
  </ul>
  <button @click="addP({name: 'xfzhang', age: 18})">添加</button>

  <h2>测试: v-for 遍历对象</h2>

  <ul>
    <li v-for="(item, key, index) in persons[0]" :key="key">{{index}}:{{key}}={{item}}</li>
  </ul>

  <button @click="test">修改名字</button>

</div>

<script type="text/javascript" src="../public/cdn/vue/2.6.10/vue.min.js"></script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      persons: [
        {name: 'Tom', age:18},
        {name: 'Jack', age:17},
        {name: 'Bob', age:19},
        {name: 'Mary', age:16}
      ]
    },

    methods: {
      deleteP (index) {
        // 方法一
        // Vue 将被侦听的数组的变更方法进行了包裹，所以它们也将会触发视图更新。这些被包裹过的方法包括：push(),pop(),shift(),unshift(),splice(),sort(),reverse()
        // this.persons.splice(index, 1) // vue包装后做了两件事 1. 调用原生的数组的对应方法 2. 更新界面

        // 方法二
        // filter()、concat() 和 slice()。它们不会变更原始数组，而总是返回一个新数组
        // Vue并不是重新渲染整个列表，vue做了优化，所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。
        this.persons = this.persons.filter((item,idx) => idx != index)
      },

      updateP (index, newP) {
        console.log('updateP', index, newP)
        // this.persons[index] = newP  // vue根本就不知道
        this.persons.splice(index, 1, newP)
        // this.persons = []  // 效果：清空了persons
      },

      addP (newP) {
        this.persons.push(newP)
      },
      test() {
        // 由于 JavaScript 的限制，Vue 不能检测数组和对象内部数据的改变
        // TODO 测试后发现改变persons内部元素，页面会刷新
        this.persons[0].name = 'pwd'
      }
    }
  })
</script>
</body>
</html>